#include "lcd.h"
#include "main.h"
#include "types.h"
#include <avr/io.h>
#include <util/delay.h>

void _lcd_OutNibble( byte nibbleToWrite )
{
  if( nibbleToWrite & B4 )
    LCD_DATA_PORT |= B4;
  else
    LCD_DATA_PORT &= ~B4;
  
  if( nibbleToWrite & B5 )
    LCD_DATA_PORT |= B5;
  else
    LCD_DATA_PORT &= ~B5;
  
  if( nibbleToWrite & B6 )
    LCD_DATA_PORT |= B6;
  else
    LCD_DATA_PORT &= ~B6;
  
  if( nibbleToWrite & B7 )
    LCD_DATA_PORT |= B7;
  else
    LCD_DATA_PORT &= ~B7;
}

// ---------- clears the display -----------------------------------------------------------
void lcd_clear()
{
  lcd_command( LCD_CLEAR );
  //_delay_ms(2);
  
  return;
}

// ---------- sets cursor to home -----------------------------------------------------------
void lcd_home()
{
   lcd_command( LCD_RETURN_HOME );
   //_delay_ms(2);
   
  return;
}

// ---------- sets cursor to first line ----------------------------------------------------
void lcd_goto1line()
{
  lcd_command( LCD_FIRST_LINE );
}
// ---------- sets cursor to second line ---------------------------------------------------
void lcd_goto2line()
{
  lcd_command( LCD_SECOND_LINE );
}

// ---------- sends a command --------------------------------------------------------------
void lcd_command( byte cmd )
{
  LCD_RS_COMMAND();				// set to command
  LCD_RW_WRITE();				// set to write
  LCD_ENABLE();					// E = 1
  _lcd_OutNibble( cmd );			// send older half-byte to port
  LCD_DISABLE();				// E = 0
  NOP;
  LCD_ENABLE();					// E = 1
  _lcd_OutNibble( cmd << 0x4 );			// send younger half-byte to port
  LCD_DISABLE();				// E = 0
  NOP;
  LCD_ENABLE();					// E = 1
  
  return;
}

// ---------- sends a data ----------------------------------------------------------------
void lcd_data( byte dat )
{
  LCD_RS_DATA();				// set to data
  LCD_RW_WRITE();				// set to write
  LCD_ENABLE();					// E = 1
  _lcd_OutNibble( dat );
  LCD_DISABLE();				// E = 0
  NOP;
  LCD_ENABLE();					// E = 1
  _lcd_OutNibble( dat << 0x4 );			// send younger half-byte to port
  LCD_DISABLE();				// E = 0
  NOP;
  LCD_ENABLE();					// E = 1
  
  return;
}

// ---------- sends a data ----------------------------------------------------------------
void lcd_text(char* text, byte len)
{
  byte i;
  for(i = 0; i < len; i++)
  {
    lcd_data( *(text + i) );
  }
  
  return;
}

// ---------- initializes the display -------------------------------------------------------
void lcd_init()
{
  byte i;
  
  LCD_RS_COMMAND();
  
  for(i =0x00 ; i < 0x03; i++)
  {
    LCD_ENABLE();		// E = 1
    _lcd_OutNibble( 0x30 );	// interfejs 8b
    LCD_DISABLE();		// E = 0
    _delay_ms(5);		// wait 5ms
  }
  
  _lcd_OutNibble(0x20 );	// interface 4b
  _delay_ms(1);
  
  lcd_command( LCD_FUNCTION_SET );
  _delay_ms(2);
  
  lcd_command( LCD_ENTRY_MODE );
  _delay_ms(2);
  
  lcd_command( LCD_DISPLAY_ON );
  
  return;
}